package com.cloud.school.app.config.security;

import com.cloud.school.app.config.CacheService;
import com.cloud.school.app.config.controller.ResThreadLocal;
import com.cloud.school.app.util.exception.UserNotLoginException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName: JWTFilter
 * @Description: 验证JWT Token的过滤器
 * @author: Administrator
 * @date: 2017年12月3日 下午5:36:16
 */
@Slf4j
public class JWTFilter extends GenericFilterBean {

    private final CacheService cacheService;

    public JWTFilter(CacheService cacheService) {
        this.cacheService = cacheService;
    }

    /**
     * <p>Title: doFilter</p>
     * <p>Description: token验证过滤器</p>
     *
     * @param request
     * @param response
     * @param filter
     * @throws IOException
     * @throws ServletException
     * @see javax.servlet.Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        try {
            // 从Request请求头中获取token
            String jwt = JWTUtils.resolveToken(httpServletRequest);
            // 验证token是否合法,是否失效
            if (StringUtils.hasText(jwt) && JWTUtils.validateToken(jwt)) {
                // 进行安全检查
                Authentication authentication = JWTUtils.getAuthentication(jwt, cacheService);
                // 在上下文中设置用户权限信息
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
            ResThreadLocal.setUrl(httpServletRequest.getServletPath() + httpServletRequest.getQueryString());
            // 执行过滤器
            filter.doFilter(request, response);
        } catch (UserNotLoginException e) {
            log.error("用户未登陆,原因{}", e.getMessage());
            httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        } catch (AuthenticationException e) {
            log.error("权限验证失败,原因{}", e.getMessage());
            httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        } catch (Exception e) {
            log.error("服务器处理异常,原因{}", e.getMessage(), e);
            httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }
}